package cn.iune.erp.sale;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.justep.baas.Utils;
import com.justep.baas.data.Row;
import com.justep.baas.data.RowState;
import com.justep.baas.data.Table;
import com.justep.baas.data.Transform;

import cn.iune.erp.core.BusinessService;

@Transactional
@Service
public class SaleOrderServiceImpl implements ISaleOrderService {
	
	@Autowired
	private ISaleOrderDao dao;
	@Autowired
	private ISaleOrderDetailDao detailDao;

	
	@Override
	public List<SaleOrder> getAll(){
		return dao.getAll();
	}
	
	@Override
	public SaleOrder getByID(String fID) {
		return dao.getByID(fID);
	}
	
	@Transactional
	@Override
	public void insert(SaleOrder obj) {
		dao.insert(obj);
	}

	@Transactional
	@Override
	public void delete(String fID) {
		dao.delete(fID);
	}
	
	@Transactional
	@Override
	public SaleOrder update(SaleOrder obj) {
		return dao.update(obj);
	}

	@Override
	public SaleOrder getByNo(String orderNo, String enterpriseNo) {
		return dao.getByNo(orderNo, enterpriseNo);
	}


	@Transactional
	@Override
	public JSONObject save(JSONObject object) throws ParseException  {
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		JSONObject data = new JSONObject();
		data.put("concept", table.getTableName());
//		JSONArray rows = new JSONArray();
//		List<String> idsNew = new ArrayList<String>();
//		List<String> idsDel = new ArrayList<String>();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			SaleOrder obj = JSON.toJavaObject(javaObject, SaleOrder.class);
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj);
//				idsNew.add(obj.getfID());
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				dao.delete(obj.getfID());
//				idsDel.add(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				dao.update(obj);
				//返回+1后的version到前台BizData中进行刷新，使得前台的version与后台的一致。
				///////////////////////////////////////////////////////////////////////
//				JSONObject jsonRow = new JSONObject();
//				jsonRow.put("id", obj.getfID());
//				jsonRow.put("version", objNew.getVersion());
//				rows.add(jsonRow);
				//////////////////////////////////////////////////////////////////////
			}
		}
		
//		data.put("rows", rows);
//		data.put("idsNew", idsNew);
//		data.put("idsDel", idsDel);
		
		data.put("code", 0);
		data.put("msg", "success");
		return data;
	}
	
	@Transactional
	@Override
	public JSONObject saveDetail(JSONObject object) throws ParseException {
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		JSONObject json = new JSONObject();
		json.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			SaleOrderDetail obj = JSON.toJavaObject(javaObject, SaleOrderDetail.class);
			if(RowState.NEW.equals(obj.getRowState())){
				detailDao.insert(obj);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				detailDao.delete(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				SaleOrderDetail objNew = detailDao.update(obj);
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
			}
		}
		
		json.put("rows", rows);
		
		return json;
	}
	
	@Override
	public List<SaleOrderDetail> getByMasterID(String fMasterID) {
		return detailDao.getByMasterID(fMasterID);
	}


	
	///////////////////////业务功能///////////////////////////////////////
	
	@Transactional
	@Override
	public int confirm(String fID) {
		SaleOrder so = dao.getByID(fID);
		if(so.getState().equals("confirm")) return 0;
		so.setState("confirm");
		so.setResultStatus("审核中");
		
		so.setOrderStatus(-1);
		so.setOrderStatusLabel("已提交");
		dao.update(so);

		return 0;
	}
	
	@Transactional
	@Override
	public int active(String fID) {
		SaleOrder so = dao.getByID(fID);
		so.setState("active");
		so.setResultStatus("待审核");
		
		so.setOrderStatus(-2);
		so.setOrderStatusLabel("待提交");

		dao.update(so);
		return 0;
	}
	
	@Transactional
	@Override
	public int close(String fID) {
		SaleOrder so = dao.getByID(fID);
		so.setStatus("close");
		dao.update(so);
		return 0;
	}
	
	@Transactional
	@Override
	public int open(String fID) {
		SaleOrder so = dao.getByID(fID);
		so.setStatus("open");
		so.seteUsercode(null);
		so.seteUsername(null);
		so.seteDatetime(null);
		dao.update(so);
		return 0;
	}
	
	@Transactional
	@Override
	public int agreeIt(String fID) {
		SaleOrder so = dao.getByID(fID);
		if(so.getAudit().equals("confirm")) return 0;
		
		so.setAudit("confirm");
		so.setConfirmDate(Utils.getCurrentDate());
		
		so.settUsercode(null);
		so.settUsername(null);
		so.settDatetime(Utils.getCurrentDateTime());

		so.setResultStatus("已审核");
		
		so.setOrderStatus(0);
		so.setOrderStatusLabel("已审核");

		dao.update(so);
		return 0;
	}
	
	@Transactional
	@Override
	public int unAgree(String fID) {
		SaleOrder so = dao.getByID(fID);
		// TODO Auto-generated method stub

		so.setAudit("active");
		so.setConfirmDate(null);
		
		so.settUsercode(null);
		so.settUsername(null);
		so.settDatetime(null);
		
		so.setResultStatus("审核中");
		
		so.setOrderStatus(-1);
		so.setOrderStatusLabel("已提交");

		dao.update(so);

		return 0;
	}
	/*
	//更新预收款金额
	@Transactional
	@Override
	public int updatePredictAmounting(String orderNo, String enterpriseNo, BigDecimal predictAmount) {

		SaleOrder so = dao.getByNo(orderNo, enterpriseNo);
		so.setPredictAmounting(so.getPredictAmounting().add(predictAmount));
		
		dao.update(so);
		//处理单据状态，如已付款或者待付款
		
		return 0;
	}
	*/

	
	//更新预收款金额（单据核销金额）
//	@Transactional
//	@Override
//	public int updatePredictAmount(String orderNo, String enterpriseNo, BigDecimal predictAmount/*, String settleCategory, String settleCategoryLabel*/) {
//		SaleOrder so = dao.getByNo(orderNo, enterpriseNo);
//		return this.updatePredictAmount(so, predictAmount/*, settleCategory, settleCategoryLabel*/);
//	}

	@Override
	public SaleOrder packing(
			String billType
			,String billTypeName 
			,String systemCode 
			,int flowType 
//			,String revOpay 
//			,int direction 
//			,String costingCode 
			,String autoCode 
			,String origin 
			,String originName 
			,String billNo 
			
			,String cUsercode//=com.justep.system.context.ContextHelper.getOperator().getCode();
			,String cUsername//=com.justep.system.context.ContextHelper.getOperator().getName();
			,String userId //= com.justep.system.context.ContextHelper.getOperator().getID();
			,String enterpriseNo //= this.getEnterpriseNo();
			,String enterpriseName //= this.getEnterpriseName();
			){
		SaleOrder obj = new SaleOrder();
		String fID = Utils.getUUID();
		obj.setfID(fID);
		//单号
		/*
		Map<String,Object> map = usercenterService.getBillParam(billType, enterpriseNo);
		String billTypeName = (String) map.get("billTypeName");
		String systemCode = (String) map.get("systemCode");
		int flowType = (int) map.get("flowType");
//		String revOpay = (String) map.get("revOpay");
//		int direction = (int) map.get("direction");
//		String costingCode = (String) map.get("costingCode");
		String autoCode = (String) map.get("autoCode");
		String origin = "WSSC";//(String) map.get("origin");
		String originName = "网上商城";//(String) map.get("originName");
		if("Y".equals(autoCode)){
			String billNo = (String) map.get("billNo");
			obj.setOrderNo(billNo);
		}
		*/
		if("Y".equals(autoCode)){
			obj.setOrderNo(billNo);
		}
		
		obj.setBillType(billType);
		obj.setBillTypeName(billTypeName);
		obj.setSystemCode(systemCode);
		obj.setFlowType(flowType);
		obj.setOrigin(origin);
		obj.setOriginName(originName);
		
		obj.setState("active");
		obj.setStatus("open");
		obj.setAudit("active");
		obj.setOrderDate(Utils.getCurrentDate());
		
		obj.setInvoiceCategory("C");
		obj.setInvoiceCategoryLabel("C.服务性发票");
		obj.setSettleCategory("C");
		obj.setSettleCategoryLabel("C.现金");
		obj.setTaxType(1);
		obj.setTaxTypeLabel("1.应税内含");
		obj.setTaxRate(BigDecimal.ZERO);
		obj.setDepositRate(BigDecimal.ZERO);
		
		obj.setItemAmount(BigDecimal.ZERO);
		obj.setOrderAmount(BigDecimal.ZERO);
		obj.setOrderAmountOld(BigDecimal.ZERO);
		obj.setOrderAmountTax(BigDecimal.ZERO);
		obj.setOrderAmountTotal(BigDecimal.ZERO);
		
		obj.setPickItemIng(BigDecimal.ZERO);
		obj.setPickItemAmount(BigDecimal.ZERO);
		
		obj.setFreightAmount(BigDecimal.ZERO);
		
		obj.setDiscountAmount(BigDecimal.ZERO);
		obj.setDiscountCash(BigDecimal.ZERO);
		obj.setDiscountRate(BigDecimal.ONE);
		
//		obj.setPredictAmount(BigDecimal.ZERO);
		
		obj.setOrderWeight(BigDecimal.ZERO);
		
		obj.setComments("来自商城");
		
		obj.setcUsercode(cUsercode);
		obj.setcUsername(cUsername);
		obj.setcDatetime(Utils.getCurrentDateTime());
		obj.setUserId(userId);
		obj.setEnterpriseNo(enterpriseNo);
		obj.setEnterpriseName(enterpriseName);
		
		obj.setDetailsCount(0);
		obj.setDetailsCountState(0);
		obj.setMaxDetailNo(0);
		
		obj.setVersion(0);
		
		return obj;
	}
	
	@Override
	public ArrayList<BigDecimal> getAmountMonth(String year, ArrayList<String> xAxisData, String enterpriseNo) {
		// TODO Auto-generated method stub
		return dao.getAmountMonth(year, xAxisData, enterpriseNo);
	}
	
	//待审核单据数量
	@Override
	public long getUnAgreeCount(String enterpriseNo) {
		return dao.getUnAgreeCount(enterpriseNo);
	}
	
	//待支付的单据总金额
	@Override
	public BigDecimal getUnpaidXSDDAmount(String customerID, String enterpriseNo) {
		return dao.getUnpaidXSDDAmount(customerID, enterpriseNo);
	}

	@Override
	public List<SaleOrder> getBySsID(String serviceSessionID) {
		// TODO Auto-generated method stub
		return dao.getBySsID(serviceSessionID);
	}

	@Override
	public List<SaleOrder> getByLoginName(String sLoginName) {
		// TODO Auto-generated method stub
		return dao.getByLoginName(sLoginName);
	}
	
	@Override
	public JSONObject querySimple(JSONObject data) {
		try {
			return dao.querySimple(data);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", "failure");
			return json;
		}
	}

	
	//统计订单数量
	@Override
	public long getCount(String sLoginName, String handling) {
		return dao.getCount(sLoginName, handling);
	}

	//一次性支付
	//销售订单的预付款不支持多次付款，只支持一次付清，即使是预付比例不等于1，如：0.8。
	//事实上是这样的，否则也没有办法操作支付状态
	//更新预收款金额（单据核销金额）--增加
	@Transactional
	@Override
	public int oncePay(String orderNo, String enterpriseNo, BigDecimal discountCash, BigDecimal actualAmount, String guestNumber) {
		SaleOrder so = dao.getByNo(orderNo, enterpriseNo);
		if(so==null) return -1;
		//已付款
//		so.setSettleCategory(settleCategory);
//		so.setSettleCategoryLabel(settleCategoryLabel);
		
		so.setPaymentStatus("paid");
		so.setPaymentStatusLabel("已支付");
		so.setPaidDatetime(Utils.getCurrentDateTime());
		
		so.setOrderStatus(1);
		so.setOrderStatusLabel("已支付");

		so.setActualAmount(actualAmount);
		so.setDiscountCash(discountCash);
		
		so.setGuestNumber(guestNumber);
		
//		List<SaleOrderDetail> sods = detailDao.getByMasterID(so.getfID());
//		for(SaleOrderDetail sod :sods) {
//			sod.setGuestNumber(guestNumber);
//			detailDao.update(sod);
//		}
		
		
		dao.update(so);
		//处理单据状态，如已付款或者待付款
		return 0;
	}
	
	
	//反一次性支付
	//销售订单的预付款不支持多次付款，只支持一次付清，即使是预付比例不等于1，如：0.8。
	//事实上是这样的，否则也没有办法操作支付状态
	/*
	@Transactional
	@Override
	public int foncePay(String orderNo, String enterpriseNo) {
		SaleOrder so = dao.getByNo(orderNo, enterpriseNo);
		//待付款
		so.setPaymentStatus("unpaid");
		so.setPaymentStatusLabel("待支付");
		
		so.setOrderStatus("unpaid");
		so.setOrderStatusLabel("待付款");		

		so.setActualAmount(BigDecimal.ZERO);
		so.setDiscountCash(BigDecimal.ZERO);

		dao.update(so);
		//处理单据状态，如已付款或者待付款
		return 0;
	}
	*/


	//已发货（更新为待收货状态）
	@Transactional
	@Override
	public int delivered(SaleOrder so) {
		if(so==null) return -1;
		so.setOrderStatus(6);
		so.setOrderStatusLabel("发货完成");
		dao.update(so);
		return 0;
	}

	//已发货（更新为待收货状态）
	@Transactional
	@Override
	public int delivered(String orderNo, String enterpriseNo) {
		SaleOrder so = dao.getByNo(orderNo, enterpriseNo);
		return this.delivered(so);
	}
	
	//已发货（更新为待收货状态）
	@Transactional
	@Override
	public int delivered(String fID) {
		SaleOrder so = dao.getByID(fID);
		return this.delivered(so);
	}

	//已完成（更新为已完成状态）
	@Transactional
	@Override
	public int finished(String fID) {

		SaleOrder so = dao.getByID(fID);
		
		so.setOrderStatus(9);
		so.setOrderStatusLabel("9.已完成");
		
		dao.update(so);
		
		return 0;
	}

	//已取消（更新为已取消状态）
	@Transactional
	@Override
	public int cancelled(String fID) {

		SaleOrder so = dao.getByID(fID);
		
		so.setStatus("cancelled");
		
		dao.update(so);
		
		return 0;
	}

	
	@Override
	public JSONObject newData(JSONObject data) {
		return dao.create(data);
	}
	
	@Override
	public JSONObject deleteData(JSONObject param) {
		
		JSONArray ids = param.getJSONArray("ids");
		for(int i=0;i<ids.size();i++){
			String id = ids.getString(i);
			//这里可以增加是否可删除的判断
			
			//首先删除子表
			List<SaleOrderDetail> sods = detailDao.getByMasterID(id);
			for(SaleOrderDetail sod:sods){
				detailDao.delete(sod.getfID());
			}

			//然后删除主表
			dao.delete(id);
		}

		JSONObject data = new JSONObject();
		data.put("ids", ids);
		
		JSONObject json = new JSONObject();
		json.put("code", 0);
		json.put("msg", "success");
		json.put("data", data);
		
		return json;
	}
	
	@Override
	public JSONObject saveData(JSONObject param) {
		// TODO Auto-generated method stub
		JSONObject data;
		try {
			//保存主表
			data = this.save(param);
			
			//保存从表
			JSONArray slaves = param.getJSONArray("slaves");
			JSONObject slaveParam = slaves.getJSONObject(0);
			
			JSONObject slaveData = this.saveDetail(slaveParam);
			
			JSONArray slaveDatas = new JSONArray();
			slaveDatas.add(slaveData);
			data.put("slaves", slaveDatas);
					
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", data);
			
			return json;
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			
			return json;
		} 
	}
	
	@Override
	public JSONObject queryData(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = dao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	
	@Override
	public JSONObject jointData(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = dao.joint(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	
	@Override
	public JSONObject validData(JSONObject param) {
		// TODO Auto-generated method stub
		return null;
	}

	//新增子表
	@Override
	public JSONObject newDataDetail(JSONObject data) {
		return detailDao.create(data);
	}
	
	//查询子表
	@Override
	public JSONObject queryDataDetail(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = detailDao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	

	//更新正在入库数量
	@Transactional
	@Override
	public int updateStoreItemAmount(
			String orderNo
			,String serialNo			
			,String enterpriseNo			
			,BigDecimal storeItemAmount 	//入库数量（合格数量）
		 	){
	
		SaleOrderDetail s = detailDao.getByNo(orderNo, serialNo, enterpriseNo);
		
		s.setStoreItemAmount(s.getStoreItemAmount().add(storeItemAmount));
		detailDao.update(s);
		return 0;
	}	
	

	//更新正在入库数量
	@Transactional
	@Override
	public int updatePickItemQuantityIng(String fID, BigDecimal itemQuantity) {

		SaleOrder so = dao.getByID(fID);
		so.setPickItemIng(so.getPickItemIng().add(itemQuantity));
		dao.update(so);
		
		return 0;
	}
	
	//更新入库数量
	@Transactional
	@Override
	public int updatePickItemQuantity(String fID, BigDecimal itemQuantity) {

		SaleOrder so = dao.getByID(fID);
		so.setPickItemIng(so.getPickItemIng().subtract(itemQuantity));
		so.setPickItemAmount(so.getPickItemAmount().add(itemQuantity));
		
		dao.update(so);
		
		return 0;
	}
	

	//更新正在入库数量
	@Transactional
	@Override
	public int updatePickItemQuantityIng(
			String orderNo
			,String serialNo			
			,String enterpriseNo			
			,BigDecimal itemQuantity 	//入库数量（合格数量）
			,BigDecimal wasterQuantity
			,BigDecimal ullageQuantity
			,BigDecimal arriveQuantityBack
		 	){
		
		//BigDecimal arriveQuantity = itemQuantity.add(wasterQuantity).add(ullageQuantity).add(arriveQuantityBack);
		SaleOrderDetail s = detailDao.getByNo(orderNo, serialNo, enterpriseNo);
		if(s==null) return 1;
		
		//新值保留
		s.setPickItemIng(s.getPickItemIng().add(itemQuantity));
		detailDao.update(s);
		
		//更新主表 
		int updateResult=this.updatePickItemQuantityIng(
				s.getfMasterID()
				, itemQuantity 
				);
		if (updateResult<0){
			return -1;
		}
		

		return 0;
	}	
	
	//更新入库数量
	@Transactional
	@Override
	public int updatePickItemQuantity(
			String orderNo
			,String serialNo			
			,String enterpriseNo			
			,BigDecimal itemQuantity
			,BigDecimal wasterQuantity
			,BigDecimal ullageQuantity
			,BigDecimal arriveQuantityBack
			,BigDecimal pieceQuantity
			){
		
		//BigDecimal arriveQuantity = itemQuantity.add(wasterQuantity).add(ullageQuantity).add(arriveQuantityBack);
		SaleOrderDetail s = detailDao.getByNo(orderNo, serialNo, enterpriseNo);
		if(s==null){
			return -1;
		}

		//新值保留
		s.setPickItemIng(s.getPickItemIng().subtract(itemQuantity));
		s.setPickItemAmount(s.getPickItemAmount().add(itemQuantity));
		s.setPickPiece(s.getPickPiece().add(pieceQuantity));
		detailDao.update(s);
		
		
		//更新主表 
		int updateResult=this.updatePickItemQuantity(
				s.getfMasterID()
				, itemQuantity
				);
		if (updateResult<0){
			return -1;
		}

		return 0;
	}
	
	
	//更新退库数量
	@Transactional
	@Override
	public int updateBackItemQuantity(
			String orderNo
			,String serialNo			
			,String enterpriseNo			
			,BigDecimal itemQuantity
			,BigDecimal pieceQuantity
			){
		
		SaleOrderDetail s = detailDao.getByNo(orderNo, serialNo, enterpriseNo);
		s.setBackItemAmount(s.getBackItemAmount().add(itemQuantity));
		s.setBackPiece(s.getBackPiece().add(pieceQuantity));
		
		//减少已完成出库数量
		s.setPickItemAmount(s.getPickItemAmount().subtract(itemQuantity));
		s.setPickPiece(s.getPickItemAmount().subtract(pieceQuantity));

		detailDao.update(s);

		return 0;
	}
	
	
	//更新结算方式
	@Transactional
	@Override
	public int updateSettleCategory(String fID, String settleCategory ,String settleCategoryLabel){
		SaleOrder s = dao.getByID(fID);
		if(s==null) return -1;
		s.setSettleCategory(settleCategory);
		s.setSettleCategoryLabel(settleCategoryLabel);

		dao.update(s);
		
		return 0;
	}
	
	
	//修改仓库
	@Transactional
	@Override
	public int updateStorage(
			String fID, String storageType ,String storageTypeLabel
			,String storageID, String storageNo ,String storageName, String floorNo
			,String factoryID, String factoryNo ,String factoryName
			){


		SaleOrder s = dao.getByID(fID);
		if(s==null) {
			return -1;
		}
		s.setStorageType(storageType);
		s.setStorageTypeLabel(storageTypeLabel);
		s.setStorageID(storageID);
		s.setStorageNo(storageNo);
		s.setStorageName(storageName);
		s.setFloorNo(floorNo);
		
		s.setFactoryID(factoryID);
		s.setFactoryNo(factoryNo);
		s.setFactoryName(factoryName);

		dao.update(s);
		
		//从表
		List<SaleOrderDetail> list = detailDao.getByMasterID(fID);
		for(SaleOrderDetail detail : list) {
			detail.setStorageType(storageType);
			detail.setStorageTypeLabel(storageTypeLabel);
			detail.setStorageID(storageID);
			detail.setStorageNo(storageNo);
			detail.setStorageName(storageName);
			detail.setFloorNo(floorNo);
			
			detail.setFactoryID(factoryID);
			detail.setFactoryNo(factoryNo);
			detail.setFactoryName(factoryName);

			detailDao.update(detail);
			
		}
		
		return 0;
	}


	//更新子订单数量
	@Transactional
	@Override
	public JSONObject updateDetailItemAmount(JSONObject data) {
		JSONObject json = new JSONObject();
	
		//子订单ID
		String id = data.getString("id");
		BigDecimal itemAmountNew = data.getBigDecimal("itemAmountNew");
		if(itemAmountNew.compareTo(BigDecimal.ZERO)==0) {
			json.put("code", -9);
			json.put("msg", "failure");
			json.put("status", "数量不能修改为0！");
			return json;
		}

		SaleOrderDetail saleOrderDetail = detailDao.getByID(id);
		if(saleOrderDetail==null) {
			json.put("code", -1);
			json.put("msg", "failure");
			json.put("status", "不存在！");
			return json;
		}
		
		
		String fMasterID = saleOrderDetail.getfMasterID();
		SaleOrder saleOrder = dao.getByID(fMasterID);
		if(saleOrder==null) {
			json.put("code", -2);
			json.put("msg", "failure");
			json.put("status", "单据不存在！");
			return json;
		}

		//成套销售
		String productID = saleOrderDetail.getSbomID();
		if(productID!=null) {
			//存在成套销售
			List<SaleOrderDetail> srds =  detailDao.getByMasterID(fMasterID);
			//先处理主件
			//保留主件修改前的数量
			BigDecimal itemAmount = saleOrderDetail.getItemAmount();//BigDecimal.ZERO;
			//处理元件
			for(SaleOrderDetail srd :srds){
				if(productID.equals(srd.getSbomID()) && srd.getLv()==1){
					//元件
					//计算数量
					BigDecimal itemAmount1 = srd.getItemAmount().divide(itemAmount).multiply(itemAmountNew).setScale(2);
					
					//统计主表金额
					///////////////////////////////////////////////////////
					//减去修改数量之前的数据
					//应该不需要设定下面的条件，因为如果是元件，应该自身的金额就是0
//					if(srd.getSttts()==1) {
						//是计价行
						saleOrder.setOrderAmount(saleOrder.getOrderAmount().subtract(srd.getOrderAmount()));
						saleOrder.setOrderAmountOld(saleOrder.getOrderAmountOld().subtract(srd.getOrderAmountOld()));
						saleOrder.setOrderAmountTax(saleOrder.getOrderAmountTax().subtract(srd.getOrderAmountTax()));
						saleOrder.setOrderAmountTotal(saleOrder.getOrderAmountTotal().subtract(srd.getOrderAmountTotal()));
//					}
					if(srd.getCheckin()==1) {
						//出入库登记的物料才计入单据总数量
						saleOrder.setItemAmount(saleOrder.getItemAmount().subtract(srd.getItemAmount()));
					}
					///////////////////////////////////////////////////////
					
					//修改之前，反审核以确保库存数量正确
//					this.unAgreeSaleOrderDetail(srd.getfID());
//					this.activeSaleOrderDetail(srd.getfID());
					
//					detailDao.updateItemAmount(srd.getfID(), itemAmount1);
					
					//修改数量
					srd.setItemAmount(itemAmount1);
					
					//计算金额
					JSONObject jsonResult = BusinessService.taxCalculate(srd.getItemAmount(), srd.getItemPrice(), srd.getTaxType(), srd.getTaxRate(), srd.getDiscountRate());
					
					srd.setOrderAmount(jsonResult.getBigDecimal("orderAmount"));
					srd.setOrderAmountOld(jsonResult.getBigDecimal("orderAmountOld"));
					srd.setOrderAmountTax(jsonResult.getBigDecimal("orderAmountTax"));
					srd.setOrderAmountTotal(jsonResult.getBigDecimal("orderAmountTotal"));
					
					//更新子表
					detailDao.update(srd);
					
					//修改之后，重新审核
//					this.confirmSaleOrderDetail(srd.getfID());
//					this.agreeItSaleOrderDetail(srd.getfID());
					
					//统计主表金额
					///////////////////////////////////////////////////////
					//累加修改数量之后的数据
					//应该不需要设定下面的条件，因为如果是元件，应该自身的金额就是0
//					if(srd.getSttts()==1) {
						//是计价行
						saleOrder.setOrderAmount(saleOrder.getOrderAmount().add(srd.getOrderAmount()));
						saleOrder.setOrderAmountOld(saleOrder.getOrderAmountOld().add(srd.getOrderAmountOld()));
						saleOrder.setOrderAmountTax(saleOrder.getOrderAmountTax().add(srd.getOrderAmountTax()));
						saleOrder.setOrderAmountTotal(saleOrder.getOrderAmountTotal().add(srd.getOrderAmountTotal()));
//					}
					if(srd.getCheckin()==1) {
						//出入库登记的物料才计入单据总数量
						saleOrder.setItemAmount(saleOrder.getItemAmount().add(srd.getItemAmount()));
					}
					///////////////////////////////////////////////////////
				}
			}
			
		}


		///////////////////////////////////////////////////////
		//减去修改数量之前的数据
		//应该不需要设定下面的条件，因为如果是元件，应该自身的金额就是0
//		if(saleOrderDetail.getSttts()==1) {
			//是计价行
			saleOrder.setOrderAmount(saleOrder.getOrderAmount().subtract(saleOrderDetail.getOrderAmount()));
			saleOrder.setOrderAmountOld(saleOrder.getOrderAmountOld().subtract(saleOrderDetail.getOrderAmountOld()));
			saleOrder.setOrderAmountTax(saleOrder.getOrderAmountTax().subtract(saleOrderDetail.getOrderAmountTax()));
			saleOrder.setOrderAmountTotal(saleOrder.getOrderAmountTotal().subtract(saleOrderDetail.getOrderAmountTotal()));
//		}

		if(saleOrderDetail.getCheckin()==1) {
			//出入库登记的物料才计入单据总数量
			saleOrder.setItemAmount(saleOrder.getItemAmount().subtract(saleOrderDetail.getItemAmount()));
		}
		///////////////////////////////////////////////////////

		//修改之前，反审核以确保库存数量正确
//		this.unAgreeSaleOrderDetail(saleOrderDetail.getfID());
//		this.activeSaleOrderDetail(saleOrderDetail.getfID());
		
//		detailDao.updateItemAmount(id, itemAmountNew);
		
		//修改数量
		saleOrderDetail.setItemAmount(itemAmountNew);
		
		//计算金额
		JSONObject jsonResult = BusinessService.taxCalculate(saleOrderDetail.getItemAmount(), saleOrderDetail.getItemPrice(), saleOrderDetail.getTaxType(), saleOrderDetail.getTaxRate(), saleOrderDetail.getDiscountRate());
		
		saleOrderDetail.setOrderAmount(jsonResult.getBigDecimal("orderAmount"));
		saleOrderDetail.setOrderAmountOld(jsonResult.getBigDecimal("orderAmountOld"));
		saleOrderDetail.setOrderAmountTax(jsonResult.getBigDecimal("orderAmountTax"));
		saleOrderDetail.setOrderAmountTotal(jsonResult.getBigDecimal("orderAmountTotal"));
		
		//更新子表
		detailDao.update(saleOrderDetail);
		
		//修改之后，重新审核
//		this.confirmSaleOrderDetail(saleOrderDetail.getfID());
//		this.agreeItSaleOrderDetail(saleOrderDetail.getfID());

		///////////////////////////////////////////////////////
		//累加修改数量之后的数据
		//应该不需要设定下面的条件，因为如果是元件，应该自身的金额就是0
//		if(saleOrderDetail.getSttts()==1) {
			//是计价行
			saleOrder.setOrderAmount(saleOrder.getOrderAmount().add(saleOrderDetail.getOrderAmount()));
			saleOrder.setOrderAmountOld(saleOrder.getOrderAmountOld().add(saleOrderDetail.getOrderAmountOld()));
			saleOrder.setOrderAmountTax(saleOrder.getOrderAmountTax().add(saleOrderDetail.getOrderAmountTax()));
			saleOrder.setOrderAmountTotal(saleOrder.getOrderAmountTotal().add(saleOrderDetail.getOrderAmountTotal()));
//		}

		if(saleOrderDetail.getCheckin()==1) {
			//出入库登记的物料才计入单据总数量
			saleOrder.setItemAmount(saleOrder.getItemAmount().add(saleOrderDetail.getItemAmount()));
		}
		///////////////////////////////////////////////////////
		
		
		//更新主表
		dao.update(saleOrder);
		
		json.put("code", 0);
		json.put("status", "成功！");
		json.put("msg", "success");
		json.put("data", fMasterID);
		
		return json;
	}

	//整单打折
	@Transactional
	@Override
	public JSONObject discountAmount(String fID, BigDecimal discountAmountTotal) {
		JSONObject json = new JSONObject();
		SaleOrder obj = dao.getByID(fID);
		if(obj==null) {
			json.put("code", -1);
			json.put("msg", "failure");
			json.put("status", "失败！");
			return json;
		}
		return this.discountAmount(obj, discountAmountTotal);
	}

	//整单打折
	@Transactional
	@Override
	public JSONObject discountAmount(SaleOrder obj, BigDecimal discountAmountTotal) {
		JSONObject json = new JSONObject();
		String fID = obj.getfID();
		List<SaleOrderDetail> saleOrderDetailList = detailDao.getByMasterID(fID);
		int taxType = obj.getTaxType();
		
		//含税：按orderAmount比例分配
		if(taxType==1 ||taxType==-1) {
			///////////////////////////////////////////////////
			BigDecimal orderAmountMaster = obj.getOrderAmount();
			////////////////////////////////////////////////////
			
			obj.setOrderAmount(BigDecimal.ZERO);
			obj.setOrderAmountOld(BigDecimal.ZERO);
			obj.setOrderAmountTax(BigDecimal.ZERO);
			obj.setOrderAmountTotal(BigDecimal.ZERO);
			
			if(orderAmountMaster.compareTo(BigDecimal.ZERO)==0) {
				//失败
				json.put("code", -1);
				json.put("msg", "failure");
				json.put("status", "失败，被除数为0！");
				return json;
			}
			for(SaleOrderDetail detail :saleOrderDetailList){
				
				////////////////////////////////////////////////
				BigDecimal orderAmount = detail.getOrderAmount();
				////////////////////////////////////////////////
				
				BigDecimal splitRate = orderAmount.divide(orderAmountMaster,10,RoundingMode.HALF_UP);
				
				////////////////////////////////////////////////////
				BigDecimal discountAmount = discountAmountTotal.multiply(splitRate).setScale(2,RoundingMode.HALF_UP);
				BigDecimal taxRate = detail.getTaxRate();
				/////////////////////////////////////////////////////
				
				detail.setDiscountAmount(discountAmount);
				//重新计税
				BigDecimal itemAmount = detail.getItemAmount();
				BigDecimal itemPrice = detail.getItemPrice();
				BigDecimal discountRate = detail.getDiscountRate();

				List<BigDecimal> taxList = BusinessService.taxCalculate(itemAmount, itemPrice, discountRate, discountAmount, taxType, taxRate);
				
				detail.setOrderAmount(taxList.get(0));
				detail.setOrderAmountOld(taxList.get(1));
				detail.setOrderAmountTax(taxList.get(2));
				detail.setOrderAmountTotal(taxList.get(3));
				
				obj.setOrderAmount(obj.getOrderAmount().add(detail.getOrderAmount()));
				obj.setOrderAmountOld(obj.getOrderAmountOld().add(detail.getOrderAmountOld()));
				obj.setOrderAmountTax(obj.getOrderAmountTax().add(detail.getOrderAmountTax()));
				obj.setOrderAmountTotal(obj.getOrderAmountTotal().add(detail.getOrderAmountTotal()));
				
		    	//saleOrderDetailService.update(detail);
			}			
		}
		
		//不含税：按orderAmountTotal比例分配
		if(taxType==0) {
			///////////////////////////////////////////////////
			BigDecimal orderAmountMaster = obj.getOrderAmountTotal();
			////////////////////////////////////////////////////
			
			obj.setOrderAmount(BigDecimal.ZERO);
			obj.setOrderAmountOld(BigDecimal.ZERO);
			obj.setOrderAmountTax(BigDecimal.ZERO);
			obj.setOrderAmountTotal(BigDecimal.ZERO);

			if(orderAmountMaster.compareTo(BigDecimal.ZERO)==0) {
				//失败
				json.put("code", -1);
				json.put("msg", "failure");
				json.put("status", "失败，被除数为0！");
				return json;
			}
			for(SaleOrderDetail detail :saleOrderDetailList){
				
				////////////////////////////////////////////////
				BigDecimal orderAmount = detail.getOrderAmountTotal();
				////////////////////////////////////////////////
				
				BigDecimal splitRate = orderAmount.divide(orderAmountMaster,10,RoundingMode.HALF_UP);
				
				//////////////////////////////////////////////////
				BigDecimal discountAmount = discountAmountTotal.multiply(splitRate);
				BigDecimal taxRate = detail.getTaxRate();
				discountAmount = discountAmount.divide(taxRate.add(BigDecimal.ONE),2,RoundingMode.HALF_UP);
				//////////////////////////////////////////////////
				
				detail.setDiscountAmount(discountAmount);
				//重新计税
				BigDecimal itemAmount = detail.getItemAmount();
				BigDecimal itemPrice = detail.getItemPrice();
				BigDecimal discountRate = detail.getDiscountRate();

				List<BigDecimal> taxList = BusinessService.taxCalculate(itemAmount, itemPrice, discountRate, discountAmount, taxType, taxRate);
				
				detail.setOrderAmount(taxList.get(0));
				detail.setOrderAmountOld(taxList.get(1));
				detail.setOrderAmountTax(taxList.get(2));
				detail.setOrderAmountTotal(taxList.get(3));
				
				obj.setOrderAmount(obj.getOrderAmount().add(detail.getOrderAmount()));
				obj.setOrderAmountOld(obj.getOrderAmountOld().add(detail.getOrderAmountOld()));
				obj.setOrderAmountTax(obj.getOrderAmountTax().add(detail.getOrderAmountTax()));
				obj.setOrderAmountTotal(obj.getOrderAmountTotal().add(detail.getOrderAmountTotal()));
				
		    	//saleOrderDetailService.update(detail);
			}			
		}

		for(SaleOrderDetail detail :saleOrderDetailList){
			detailDao.update(detail);
		}
		
		//主表
		obj.setDiscountAmount(discountAmountTotal);
		dao.update(obj);
		
		int rtn = 0;
		if(rtn==0) {
			//成功
			json.put("code", 0);
			json.put("msg", "success");
			json.put("status", "成功！");
			return json;
		}else {
			//失败
			json.put("code", -1);
			json.put("msg", "failure");
			json.put("status", "失败！");
			return json;
		}
	}


	//更新会员信息
	@Transactional
	@Override
	public SaleOrder updateCustomer(String fID,
			String storageTypeD,
			String storageTypeDLabel,
			String customerID,
			String customerNo,
			String shortName,
			String customerName
			){
		
		JSONObject json = new JSONObject();
		
//		String storageTypeD = data.getString("storageTypeD");
//		String storageTypeDLabel = data.getString("storageTypeDLabel");
//		String customerID = data.getString("customerID");
//		String customerNo = data.getString("customerNo");
//		String shortName = data.getString("shortName");
//		String customerName = data.getString("customerName");
		
		/*
		String customerID = data.getString("customerID");
		FileCustomer fileCustomer = fileCustomerService.getByID(customerID);
		if(fileCustomer==null){
			json.put("code", -1);
			json.put("result", "会员不存在！");
		}
		
		String storageTypeD = fileCustomer.getStorageTypeD();
		String storageTypeDLabel = fileCustomer.getStorageTypeDLabel();
		String customerNo = fileCustomer.getCustomerNo();
		String shortName = fileCustomer.getShortName();
		String customerName = fileCustomer.getCustomerName();
		*/		
		
		SaleOrder saleOrder = dao.getByID(fID);
		if(saleOrder==null){
			json.put("code", -2);
			json.put("msg", "failure");
			json.put("result", "单据不存在！");
		}
		
		//后续增加会员价管理
		
		List<SaleOrderDetail> saleOrderDetails = detailDao.getByMasterID(fID);

		
		//更新主表
		saleOrder.setStorageTypeD(storageTypeD);
		saleOrder.setStorageTypeDLabel(storageTypeDLabel);
		saleOrder.setCustomerID(customerID);
		saleOrder.setCustomerNo(customerNo);
		saleOrder.setShortName(shortName);
		saleOrder.setCustomerName(customerName);
		dao.update(saleOrder);
		
		//更新从表
		for(SaleOrderDetail saleOrderDetail:saleOrderDetails){
			
			saleOrderDetail.setStorageTypeD(storageTypeD);
			saleOrderDetail.setStorageTypeDLabel(storageTypeDLabel);
			saleOrderDetail.setCustomerID(customerID);
			saleOrderDetail.setCustomerNo(customerNo);
			saleOrderDetail.setShortName(shortName);
			saleOrderDetail.setCustomerName(customerName);
			
			detailDao.update(saleOrderDetail);
		}
		
		
//		json.put("code", 0);
//		json.put("msg", "success");
//		json.put("result", "操作成功！");

		return saleOrder;
		
	}
	

	
	
	
}
